package com.example.birdfriends.utils.export;

import com.example.birdfriends.pojo.export.ExcelHeaderCell;
import com.example.birdfriends.pojo.export.constant.DataExportTypeConstant;
import com.example.birdfriends.pojo.export.constant.DataTypeConstant;
import com.example.birdfriends.service.DataExportReadService;
import com.example.birdfriends.pojo.export.vo.DataExportVo;
import com.example.birdfriends.service.DataExportWriteService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.sql.ResultSetMetaData;
import java.text.SimpleDateFormat;
import java.util.*;

public class DataExportExcelJob {
    public static final Logger logger = LoggerFactory.getLogger(DataExportExcelJob.class);
    private DataExportReadService dataExportReadService;
    private DataExportWriteService dataExportWriteService;
    private JdbcTemplate jdbcTemplate;
    private DataExportVo dataExportVo;
    // 文件总目录
    private String allFilePath;
    private String filePath;
    private List<Map<String, Object>> tableInfoMap;
    private int limit = 1000;

    public DataExportExcelJob(DataExportReadService dataExportReadService, DataExportWriteService dataExportWriteService, JdbcTemplate jdbcTemplate, String filepath){
        this.dataExportReadService = dataExportReadService;
        this.dataExportWriteService = dataExportWriteService;
        this.jdbcTemplate = jdbcTemplate;
        this.filePath = filepath;
    }

    // 初始化任务信息
    public void init(String exportId){
        dataExportVo = dataExportReadService.queryDataExportDataById(exportId);
        tableInfoMap = dataExportReadService.queryTableInfoByTableName(dataExportVo.getExportTable());
        Date exportTime = dataExportVo.getExportTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        String format = simpleDateFormat.format(exportTime);
        allFilePath = filePath + "/" + format + "/" + dataExportVo.getExportTable() + "/";
    }

    // 执行导出任务
    public void executionJob(String exportId, HttpSession session){
        try{
            init(exportId);
            logger.info("{} 开始导出", dataExportVo.getExportName());

            // 表头生成
            List<ExcelHeaderCell> excelHeaderCellList = new ArrayList<>();

            for(Map<String, Object> map: tableInfoMap){
                ExcelHeaderCell excelHeaderCell = new ExcelHeaderCell();
                excelHeaderCell.setColumnCode(String.valueOf(map.get("COLUMN_NAME")));
                excelHeaderCell.setColumnName(String.valueOf(map.get("COLUMN_NAME")));
                excelHeaderCell.setDataType(String.valueOf(map.get("DATA_TYPE")));
                excelHeaderCellList.add(excelHeaderCell);
            }
            List<DataExportVo> excelList = dataExportReadService.queryDataExportExcelListById(dataExportVo.getExportId());
            for(DataExportVo excel: excelList){
                try{
                    // 生成文件
                    singleExport(excel, excelHeaderCellList, session);
                }catch (Exception e){
                    e.printStackTrace();
                    logger.error("{}文件导出失败！", excel.getExcelId());
                }
            }
            dataExportVo.setExportStat(DataExportTypeConstant.SUCCESS_EXPORT.getValue());
            dataExportWriteService.updateDataExportStat(dataExportVo);
        }catch (Exception e){
            e.printStackTrace();
            dataExportVo.setExportStat(DataExportTypeConstant.FAIL_EXPORT.getValue());
            dataExportWriteService.updateDataExportStat(dataExportVo);
        }
        logger.info("{}导出结束", dataExportVo.getExportName());
    }

    private void singleExport(DataExportVo excel, List<ExcelHeaderCell> excelHeaderCellList, HttpSession session){
        String sql = excel.getSql();
        // 文件名称
        String fileName = excel.getExcelId()+".xlsx";
        ExcelWriteUtil excelWriteUtil = new ExcelWriteUtil(allFilePath+fileName, excelHeaderCellList);
//        System.out.println("导出文件路径："+allFilePath+fileName);
        logger.info("{}文件生成", allFilePath+fileName);
        session.setAttribute(dataExportVo.getExportTable(), allFilePath+fileName);

        // 写入数据
        int offset = 0;
        List<Map<String, Object>> data = null;
        do{
            String sqlLimit = sql + " limit " + limit + " offset " + offset;
            // 执行sql
            data = jdbcTemplate.query(sqlLimit, (resultSet, row) -> {
               Map<String, Object> res = new HashMap<>();
                ResultSetMetaData metaData = resultSet.getMetaData();
                for(int i = 1; i <= metaData.getColumnCount(); i++){
                    res.put(metaData.getColumnName(i), resultSet.getObject(i));
                }
                return res;
            });

            excelWriteUtil.writeBatch(data);
            offset += limit;
        }while ((!data.isEmpty()) && data.size() == limit);
        excelWriteUtil.flush();
    }
}
